Completed
Push — master ( 789c09...13763e )
by Ruben de
05:19 queued 03:08
created

scribe(ꞌtest wallet list transactions and addressesꞌ)   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
dl 0
loc 62
rs 9.4743
nop 0

4 Functions

Rating   Name   Duplication   Size   Complexity  
A wallet.test.js ➔ ... ➔ it(ꞌshould existsꞌ) 0 23 1
A wallet.test.js ➔ ... ➔ it(ꞌshould list UTXOsꞌ) 0 10 1
A wallet.test.js ➔ ... ➔ it(ꞌshould list expected transactionsꞌ) 0 11 1
A wallet.test.js ➔ ... ➔ it(ꞌshould list expected addressesꞌ) 0 11 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/* jshint -W101, -W098 */
2
/* global window */
3
var _ = require('lodash');
4
var blocktrail = require('../');
5
var Wallet = blocktrail.Wallet;
6
var assert = require('assert');
7
var crypto = require('crypto');
8
var async = require('async');
9
var bitcoin = require('bitcoinjs-lib');
10
var bip39 = require("bip39");
11
12
var WAIT_FOR_TX_PROCESSED = process.env.BLOCKTRAIL_WAIT_FOR_TX || 300;
13
14
/**
15
 * @type APIClient
16
 */
17
var client = blocktrail.BlocktrailSDK({
18
    apiKey : process.env.BLOCKTRAIL_SDK_APIKEY || window.BLOCKTRAIL_SDK_APIKEY || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APIKEY",
19
    apiSecret : process.env.BLOCKTRAIL_SDK_APISECRET || window.BLOCKTRAIL_SDK_APISECRET || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APISECRET",
20
    testnet : true
21
});
22
23
var TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC = "give pause forget seed dance crawl situate hole keen",
24
    TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC = "give pause forget seed dance crawl situate hole give",
25
    TRANSACTION_TEST_WALLET_PASSWORD = "password";
26
27 View Code Duplication
var _createTestWallet = function(identifier, passphrase, primaryMnemonic, backupMnemonic, segwit, cb) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
28
    var keyIndex = 9999;
29
    var network = client.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
30
31
    var primarySeed = bip39.mnemonicToSeed(primaryMnemonic, passphrase);
32
    var primaryPrivateKey = bitcoin.HDNode.fromSeedBuffer(primarySeed, network);
33
34
    var backupSeed = bip39.mnemonicToSeed(backupMnemonic, "");
35
    var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(backupSeed, network);
36
    var backupPublicKey = backupPrivateKey.neutered();
37
38
    var checksum = primaryPrivateKey.getAddress();
39
    var primaryPublicKey = primaryPrivateKey.deriveHardened(keyIndex).neutered();
40
41
    client.storeNewWalletV1(
42
        identifier,
43
        [primaryPublicKey.toBase58(), "M/" + keyIndex + "'"],
44
        [backupPublicKey.toBase58(), "M"],
45
        primaryMnemonic,
46
        checksum,
47
        keyIndex,
48
        segwit
49
    ).then(function(result) {
50
        var blocktrailPublicKeys = _.mapValues(result.blocktrail_public_keys, function(blocktrailPublicKey) {
51
            return bitcoin.HDNode.fromBase58(blocktrailPublicKey[0], network);
52
        });
53
54
        var wallet = new blocktrail.Wallet(
55
            client,
56
            identifier,
57
            blocktrail.Wallet.WALLET_VERSION_V1,
58
            primaryMnemonic,
59
            null,
60
            null,
61
            {keyIndex: primaryPublicKey},
62
            backupPublicKey,
63
            blocktrailPublicKeys,
64
            keyIndex,
65
            result.segwit || 0,
66
            client.testnet,
67
            checksum
68
        );
69
70
        wallet.unlock({
71
            passphrase: passphrase
72
        }, function(err) {
73
            cb(err, wallet);
74
        });
75
76
    }, function(err) {
77
        return cb(err);
78
    });
79
};
80
81
var createDiscoveryTestWallet = function(identifier, passphrase, cb) {
82
    var primaryMnemonic = "give pause forget seed dance crawl situate hole kingdom";
83
    var backupMnemonic = "give pause forget seed dance crawl situate hole course";
84
85
    return _createTestWallet(identifier, passphrase, primaryMnemonic, backupMnemonic, false, cb);
86
};
87
88
var createTransactionTestWallet = function(identifier, segwit, cb) {
89
    return _createTestWallet(
90
        identifier,
91
        TRANSACTION_TEST_WALLET_PASSWORD,
92
        TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC,
93
        TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC,
94
        segwit,
95
        cb
96
    );
97
};
98
99
var createRecoveryTestWallet = function(identifier, passphrase, cb) {
100
    var primaryMnemonic = "give pause forget seed dance crawl situate hole join";
101
    var backupMnemonic = "give pause forget seed dance crawl situate hole crater";
102
103
    return _createTestWallet(identifier, passphrase, primaryMnemonic, backupMnemonic, false, cb);
104
};
105
106
describe('Initialize with check_backup_key', function() {
107
    it('rejects invalid inputs', function(cb) {
108
        try {
109
            client.initWallet({
110
                identifier: "unittest-transaction",
111
                password: "password",
112
                check_backup_key: []
113
            });
114
            assert(false);
115
        } catch (e) {
116
            assert.equal("Invalid input, must provide the backup key as a string (the xpub)", e.message);
117
        }
118
        cb();
119
    });
120
121
    it('checks against the string', function(cb) {
122
        client.initWallet({
123
            identifier: "unittest-transaction",
124
            password: "password",
125
            check_backup_key: 'for demonstration purposes only'
126
        }, function(err, _wallet) {
0 ignored issues
show
Unused Code introduced by
The parameter _wallet is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
127
            assert.ok(err);
128
            assert.equal("Backup key returned from server didn't match our own copy", err.message);
129
            cb();
130
        });
131
    });
132
133
    it('allows if the backup key matches', function(cb) {
134
        // You wouldn't keep your backup seed in your code,
135
        // dump it from the wallet upon generation
136
137
        var backupSeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC, "");
138
        var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(backupSeed, bitcoin.networks.testnet);
139
        var backupPublicKey = backupPrivateKey.neutered();
140
        var xpub = backupPublicKey.toBase58();
141
142
        // Would be saves as a string in code..
143
        client.initWallet({
144
            identifier: "unittest-transaction",
145
            password: "password",
146
            check_backup_key: xpub
147
        }, function(err, _wallet) {
148
            assert.ifError(err);
149
            assert.ok(_wallet);
150
            cb();
151
        });
152
    });
153
});
154
155
/**
156
 * Test operations on v2 and v3 wallets.
157
 * Also tests the default, encouraging to look at this test if it changes again.
158
 */
159
[
160
  blocktrail.Wallet.WALLET_VERSION_V2,
161
  blocktrail.Wallet.WALLET_VERSION_V3,
162
  null /* test our assumed default version */
163
].map(function(walletVersion) {
164
    var assumedDefault = blocktrail.Wallet.WALLET_VERSION_V3;
165
    describe('test new blank wallet, ' + walletVersion, function() {
166
        var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
167
        var wallet;
168
169
        after(function(cb) {
170
            if (wallet) {
171
                wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
172
                    cb();
173
                });
174
            } else {
175
                cb();
176
            }
177
        });
178
179
        it("shouldn't already exist", function(cb) {
180
            client.initWallet({
181
                identifier: myIdentifier,
182
                readOnly: true
183
            }, function(err, wallet) {
184
                assert.ok(err);
185
                assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
186
187
                cb();
188
            });
189
        });
190
191
        it("should be created", function(cb) {
192
            var progress = [];
193
            var cnf = {
194
                identifier: myIdentifier,
195
                passphrase: "password",
196
                keyIndex: 9999
197
            };
198
199
            var expectedVersion = assumedDefault;
200
            if (walletVersion !== null) {
201
                cnf.walletVersion = walletVersion;
202
                expectedVersion = walletVersion;
203
            }
204
205
            client.createNewWallet(cnf, function(err, _wallet, backupInfo) {
0 ignored issues
show
Unused Code introduced by
The parameter backupInfo is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
206
                assert.ifError(err);
207
                assert.ok(_wallet);
208
209
                wallet = _wallet;
210
                assert.equal(wallet.walletVersion, expectedVersion);
211
                assert.equal(wallet.identifier, myIdentifier);
212
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
213
214
                assert.deepEqual(progress, [
215
                    blocktrail.CREATE_WALLET_PROGRESS_START,
216
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_SECRET,
217
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_PRIMARY,
218
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_RECOVERY,
219
                    blocktrail.CREATE_WALLET_PROGRESS_PRIMARY,
220
                    blocktrail.CREATE_WALLET_PROGRESS_BACKUP,
221
                    blocktrail.CREATE_WALLET_PROGRESS_SUBMIT,
222
                    blocktrail.CREATE_WALLET_PROGRESS_INIT,
223
                    blocktrail.CREATE_WALLET_PROGRESS_DONE
224
                ]);
225
226
                cb();
227
            })
228
            .progress(function(p) { progress.push(p); });
229
        });
230
231
        it("should lock", function(cb) {
232
            assert(!wallet.locked);
233
            wallet.lock();
234
            assert(wallet.locked);
235
            cb();
236
        });
237
238
        it("should init", function(cb) {
239
            client.initWallet({
240
                identifier: myIdentifier,
241
                readOnly: true
242
            }, function(err, _wallet) {
243
                assert.ifError(err);
244
                assert.ok(_wallet);
245
246
                wallet = _wallet;
247
248
                cb();
249
            });
250
        });
251
252
        it("should have a 0 balance", function(cb) {
253
            wallet.getBalance(function(err, confirmed, unconfirmed) {
254
                assert.ifError(err);
255
                assert.equal(confirmed, 0);
256
                assert.equal(unconfirmed, 0);
257
258
                cb();
259
            });
260
        });
261
262
        it("shouldn't be able to pay when locked", function(cb) {
263
            wallet.pay({
264
                "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
265
            }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
266
                assert.ok(!!err && err.message.match(/unlocked/));
267
                assert.ok(err instanceof blocktrail.WalletLockedError);
268
269
                cb();
270
            });
271
        });
272
273
        it("shouldn't be able to upgrade when locked", function(cb) {
274
            wallet.upgradeKeyIndex(10000, function(err) {
275
                assert.ok(!!err && err.message.match(/unlocked/));
276
                assert.ok(err instanceof blocktrail.WalletLockedError);
277
278
                cb();
279
            });
280
        });
281
282
        it("should unlock", function(cb) {
283
            wallet.unlock({password: "password"}, function(err) {
284
                assert.ifError(err);
285
286
                cb();
287
            });
288
        });
289
290
        it("should be able to unlock with secret", function(cb) {
291
            var secret = wallet.secret;
292
293
            wallet.lock();
294
            wallet.unlock({secret: secret}, function(err) {
295
                assert.ifError(err);
296
                cb();
297
            });
298
        });
299
300
        it("shouldn't be able to pay when unlocked (because of no balance)", function(cb) {
301
            wallet.pay({
302
                "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
303
            }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
304
                assert.ok(!!err && err.message.match(/balance/));
305
306
                cb();
307
            });
308
        });
309
310
        it("should be able to upgrade when unlocked", function(cb) {
311
            wallet.upgradeKeyIndex(10000, function(err) {
312
                assert.ifError(err);
313
314
                cb();
315
            });
316
        });
317
318
        it("should be able to password change", function(cb) {
319
            wallet.passwordChange("password2", function(err) {
320
                assert.ifError(err);
321
322
                client.initWallet({
323
                    identifier: myIdentifier,
324
                    password: "password2"
325
                }, function(err, _wallet) {
326
                    assert.ifError(err);
327
                    assert.ok(_wallet);
328
329
                    wallet = _wallet;
330
331
                    cb();
332
                });
333
            });
334
        });
335
    });
336
});
337
338
/**
339
 * Test operations on v2 and v3 wallets.
340
 */
341
[
342
    blocktrail.Wallet.WALLET_VERSION_V1,
343
    blocktrail.Wallet.WALLET_VERSION_V2,
344
    blocktrail.Wallet.WALLET_VERSION_V3
345
].map(function(walletVersion) {
346
    var primarySeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_PASSWORD);
347
348
    describe('test input errors, ' + walletVersion, function() {
349
        it("shouldn't allow primaryPrivateKey in creation", function(cb) {
350
            var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
351
            var primaryPrivateKey = bitcoin.HDNode.fromSeedBuffer(primarySeed, bitcoin.networks.testnet);
352
353
            client.createNewWallet({
354
                identifier: myIdentifier,
355
                passphrase: "password",
356
                primaryPrivateKey: primaryPrivateKey,
357
                walletVersion: walletVersion,
358
                keyIndex: 9999
359
            }, function(err, wallet) {
0 ignored issues
show
Unused Code introduced by
The parameter wallet is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
360
                assert.ok(!!err, "should error");
361
362
                cb();
363
            });
364
        });
365
366
        it("shouldn't allow unlocking with primaryPrivateKey", function(cb) {
367
            client.createNewWallet({
368
                identifier: "unittest-transaction-inputerr-" + walletVersion,
369
                primarySeed: primarySeed,
370
                walletVersion: walletVersion,
371
                keyIndex: 9999
372
            }).then(function(r) {
373
                var wallet = r[0];
374
                wallet.lock();
375
                return wallet;
376
            }, function(err) {
377
                assert.ok(err.message.match(/already exists/));
378
379
                return client.initWallet({
380
                    identifier: "unittest-transaction-inputerr-" + walletVersion,
381
                    readOnly: true
382
                });
383
            }).then(function(wallet) {
384
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
385
386
                return wallet.unlock({primaryPrivateKey: bitcoin.HDNode.fromSeedBuffer(primarySeed, bitcoin.networks.testnet)})
387
                    .then(function() {
388
                        return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
389
                    }, function(err) {
390
                        return err;
391
                    });
392
            })
393
                .then(function(err) {
394
                    assert.ok(!!err, "should error");
395
                    cb();
396
                })
397
                .done();
398
        });
399
    });
400
});
401
402
/**
403
 * Test upgrade to V3 from V1 and V2
404
 */
405
[
406
    blocktrail.Wallet.WALLET_VERSION_V1,
407
    blocktrail.Wallet.WALLET_VERSION_V2
408
].map(function(walletVersion) {
409
    describe("upgrade to V3 from " + walletVersion, function() {
410
        var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
411
        var passphrase = "password";
412
        var wallet;
413
414
        after(function(cb) {
415
            if (wallet) {
416
                wallet.deleteWallet(true, function(err, result) {
417
                    console.log(err, result);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
418
                    cb();
419
                });
420
            } else {
421
                cb();
422
            }
423
        });
424
425
        it("can upgrade", function() {
426
            var addr;
427
            return client.createNewWallet({
428
                identifier: myIdentifier,
429
                passphrase: passphrase,
430
                walletVersion: walletVersion,
431
                keyIndex: 9999
432
            })
433
                .then(function(r) {
434
                    return r[0];
435
                })
436
                .then(function(_wallet) {
437
                    wallet = _wallet;
438
                    addr = wallet.getAddressByPath("M/9999'/0/0");
439
440
                    return wallet;
441
                })
442
                .then(function(wallet) {
443
                    var progress = [];
444
445
                    return wallet.upgradeToV3(passphrase)
446
                        .progress(function(p) {
447
                            progress.push(p);
448
                        })
449
                        .then(function() {
450
                            assert(progress.length);
451
                            return wallet;
452
                        });
453
                })
454
                .then(function(wallet) {
455
                    assert.equal(addr, wallet.getAddressByPath("M/9999'/0/0"));
456
                });
457
        });
458
459
        it("can unlock with secret", function() {
460
            var secret = wallet.secret;
461
            wallet.lock();
462
            return wallet.unlock({secret: secret});
463
        });
464
465
        it("can init after upgrade", function() {
466
            return client.initWallet({
467
                identifier: myIdentifier,
468
                passphrase: passphrase,
469
                keyIndex: 9999
470
            });
471
        });
472
    });
473
});
474
475
describe('test new blank wallet, v1', function() {
476
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
477
    var wallet;
478
479
    after(function(cb) {
480
        if (wallet) {
481
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
482
                cb();
483
            });
484
        } else {
485
            cb();
486
        }
487
    });
488
489
    it("shouldn't already exist", function(cb) {
490
        client.initWallet({
491
            identifier: myIdentifier,
492
            readOnly: true
493
        }, function(err, wallet) {
494
            assert.ok(err);
495
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
496
497
            cb();
498
        });
499
    });
500
501
    it("should be created", function(cb) {
502
        var progress = [];
503
504
        client.createNewWallet({
505
                identifier: myIdentifier,
506
                passphrase: "password",
507
                keyIndex: 9999,
508
                walletVersion: blocktrail.Wallet.WALLET_VERSION_V1
509
            }, function(err, _wallet) {
510
                assert.ifError(err);
511
                assert.ok(_wallet);
512
513
                wallet = _wallet;
514
515
                assert.equal(wallet.identifier, myIdentifier);
516
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
517
518
                assert.deepEqual(progress, [
519
                    blocktrail.CREATE_WALLET_PROGRESS_START,
520
                    blocktrail.CREATE_WALLET_PROGRESS_PRIMARY,
521
                    blocktrail.CREATE_WALLET_PROGRESS_BACKUP,
522
                    blocktrail.CREATE_WALLET_PROGRESS_SUBMIT,
523
                    blocktrail.CREATE_WALLET_PROGRESS_INIT,
524
                    blocktrail.CREATE_WALLET_PROGRESS_DONE
525
                ]);
526
527
                cb();
528
            }
529
        ).progress(function(p) { progress.push(p); });
530
    });
531
532
    it("should lock", function(cb) {
533
        assert(!wallet.locked);
534
        wallet.lock();
535
        assert(wallet.locked);
536
        cb();
537
    });
538
539
    it("should init", function(cb) {
540
        client.initWallet({
541
            identifier: myIdentifier,
542
            readOnly: true
543
        }, function(err, _wallet) {
544
            assert.ifError(err);
545
            assert.ok(_wallet);
546
            assert.equal(wallet.walletVersion, 'v1');
547
548
            wallet = _wallet;
549
550
            cb();
551
        });
552
    });
553
554
    it("should have a 0 balance", function(cb) {
555
        wallet.getBalance(function(err, confirmed, unconfirmed) {
556
            assert.ifError(err);
557
            assert.equal(confirmed, 0);
558
            assert.equal(unconfirmed, 0);
559
560
            cb();
561
        });
562
    });
563
564
    it("should unlock", function(cb) {
565
        wallet.unlock({password: "password"}, function(err) {
566
            assert.ifError(err);
567
568
            cb();
569
        });
570
    });
571
572
    it("shouldn't be able to password change", function(cb) {
573
        wallet.passwordChange("password2", function(err) {
574
            assert.ok(!!err && err.message.match(/version does not support/));
575
576
            cb();
577
        });
578
    });
579
});
580
581
describe('test new blank wallet, old syntax', function() {
582
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
583
    var wallet;
584
585
    after(function(cb) {
586
        if (wallet) {
587
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
588
                cb();
589
            });
590
        } else {
591
            cb();
592
        }
593
    });
594
595
    it("shouldn't already exist", function(cb) {
596
        client.initWallet(myIdentifier, "password", function(err, wallet) {
597
            assert.ok(err);
598
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
599
600
            cb();
601
        });
602
    });
603
604
    it("should be created", function(cb) {
605
        client.createNewWallet(myIdentifier, "password", 9999, function(err, _wallet) {
606
            assert.ifError(err);
607
            assert.ok(_wallet);
608
609
            wallet = _wallet;
610
611
            assert.equal(wallet.identifier, myIdentifier);
612
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
613
            cb();
614
        });
615
    });
616
617
    it("should have a 0 balance", function(cb) {
618
        wallet.getBalance(function(err, confirmed, unconfirmed) {
619
            assert.ifError(err);
620
            assert.equal(confirmed, 0);
621
            assert.equal(unconfirmed, 0);
622
623
            cb();
624
        });
625
    });
626
627
    it("shouldn't be able to pay", function(cb) {
628
        wallet.pay({
629
            "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
630
        }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
631
            assert.ok(!!err);
632
633
            cb();
634
        });
635
    });
636
});
637
638
describe('test new wallet, without mnemonics', function() {
639
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
640
    var wallet;
641
642
    var primarySeed = bip39.mnemonicToSeed(bip39.generateMnemonic(512), "password");
643
    var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(bip39.mnemonicToSeed(bip39.generateMnemonic(512), ""), bitcoin.networks.testnet);
644
    var backupPublicKey = backupPrivateKey.neutered();
645
646
    after(function(cb) {
647
        if (wallet) {
648
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
649
                cb();
650
            });
651
        } else {
652
            cb();
653
        }
654
    });
655
656
    it("shouldn't already exist", function(cb) {
657
        client.initWallet({
658
            identifier: myIdentifier
659
        }, function(err, wallet) {
660
            assert.ok(err);
661
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
662
663
            cb();
664
        });
665
    });
666
667
    it("should be created", function(cb) {
668
        client.createNewWallet({
669
                identifier: myIdentifier,
670
                primarySeed: primarySeed,
671
                backupPublicKey: backupPublicKey,
672
                keyIndex: 9999
673
            }, function(err, _wallet) {
674
                assert.ifError(err);
675
                assert.ok(_wallet);
676
                assert.ok(!_wallet.isSegwit());
677
                assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
678
679
                wallet = _wallet;
680
681
                assert.equal(wallet.identifier, myIdentifier);
682
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
683
                cb();
684
            }
685
        );
686
    });
687
688
    it("should be initializable", function(cb) {
689
        client.initWallet({
690
                identifier: myIdentifier,
691
                primarySeed: primarySeed,
692
                keyIndex: 9999
693
            }, function(err, _wallet) {
694
                assert.ifError(err);
695
                assert.ok(_wallet);
696
                assert.ok(!_wallet.isSegwit());
697
                assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
698
699
                wallet = _wallet;
700
701
                cb();
702
            }
703
        );
704
    });
705
706
    it("should have a 0 balance", function(cb) {
707
        wallet.getBalance(function(err, confirmed, unconfirmed) {
708
            assert.ifError(err);
709
            assert.equal(confirmed, 0);
710
            assert.equal(unconfirmed, 0);
711
712
            cb();
713
        });
714
    });
715
716
    it("shouldn't be able to pay", function(cb) {
717
        wallet.pay({
718
            "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
719
        }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
720
            assert.ok(!!err);
721
722
            cb();
723
        });
724
    });
725
});
726
727
describe('test wallet, do transaction', function() {
728
    var wallet;
729
730
    it("should exists", function(cb) {
731
        client.initWallet({
732
            identifier: "unittest-transaction",
733
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
734
        }, function(err, _wallet) {
735
            assert.ifError(err);
736
            assert.ok(_wallet);
737
            assert.ok(!_wallet.isSegwit());
738
            assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
739
            wallet = _wallet;
740
741
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
742
            assert.equal(wallet.identifier, "unittest-transaction");
743
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
744
            cb();
745
        });
746
    });
747
748
    it("should have the expected addresses", function(cb) {
749
        assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD");
750
        assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2MynrezSyqCq1x5dMPtRDupTPA4sfVrNBKq");
751
        assert.equal(wallet.getAddressByPath("M/9999'/0/44"), "2N5eqrZE7LcfRyCWqpeh1T1YpMdgrq8HWzh");
752
753
        cb();
754
    });
755
756
    it("should have a balance", function(cb) {
757
        this.timeout(0);
758
759
        wallet.getBalance(function(err, confirmed, unconfirmed) {
760
            assert.ok(confirmed + unconfirmed > 0);
761
            assert.ok(confirmed > 0);
762
763
            cb();
764
        });
765
    });
766
767
    it("should return errors when expected", function(cb) {
768
        async.parallel([
769
            function(cb) {
770
                wallet.pay({"": blocktrail.toSatoshi(0.001)}, function(err) {
771
                    assert.ok(!!err);
772
                    assert.equal(err.message, "Invalid address [] (Invalid checksum)");
773
                    assert.ok(err instanceof blocktrail.InvalidAddressError);
774
775
                    cb();
776
                });
777
            },
778
            function(cb) {
779
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHA": blocktrail.toSatoshi(0.001)}, function(err) {
780
                    assert.ok(!!err);
781
                    assert.equal(err.message, "Invalid address [2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHA] (Invalid checksum)");
782
                    assert.ok(err instanceof blocktrail.InvalidAddressError);
783
784
                    cb();
785
                });
786
            },
787
            function(cb) {
788
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 1}, function(err) {
789
                    assert.ok(!!err);
790
                    assert.equal(err.message, "Values should be more than dust (" + blocktrail.DUST + ")");
791
                    assert.ok(err instanceof blocktrail.WalletSendError);
792
793
                    cb();
794
                });
795
            },
796
            function(cb) {
797
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 0}, function(err) {
798
                    assert.ok(!!err);
799
                    assert.equal(err.message, "Values should be non zero");
800
                    assert.ok(err instanceof blocktrail.WalletSendError);
801
802
                    cb();
803
                });
804
            },
805
            function(cb) {
806
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 1.1}, function(err) {
807
                    assert.ok(!!err);
808
                    assert.equal(err.message, "Values should be in Satoshis");
809
                    assert.ok(err instanceof blocktrail.WalletSendError);
810
811
                    cb();
812
                });
813
            }
814
        ], cb);
815
    });
816
817
    it("should be able to build a transaction paying a bech32 address", function(cb) {
818
        var address = "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs";
819
        var wp = "00149bce9399f9eeddad66635d4be171ec8f14decc59";
820
        var pay = {};
821
        pay[address] = blocktrail.toSatoshi(0.001);
822
823
        wallet.buildTransaction(pay, null, false, false, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
824
            assert.ifError(err);
825
            assert.ok(tx);
826
            assert.ok(tx.toHex());
827
            assert.equal(wp, tx.outs[0].script.toString('hex'));
828
            cb();
829
        });
830
    });
831
832
    it("change should be randomized when building a transaction", function(cb) {
833
        wallet.getNewAddress(function(err, address, path) {
834
            assert.ifError(err);
835
            assert.ok(path.indexOf("M/9999'/0/") === 0);
836
            assert.ok(bitcoin.address.fromBase58Check(address));
837
838
            var pay = {};
839
            pay[address] = blocktrail.toSatoshi(0.001);
840
841
            var changeIdxs = [];
842
            var tryX = 10;
843
844
            async.whilst(
845
                function() { return tryX-- > 0 && _.uniq(changeIdxs).length < 2; },
846
                function(cb) {
847
                    wallet.buildTransaction(pay, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
848
                        assert.ifError(err);
849
850
                        tx.outs.forEach(function(output, idx) {
851
                            var addr = bitcoin.address.fromOutputScript(output.script, client.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin);
852
853
                            if (addr !== address) {
854
                                changeIdxs.push(idx);
855
                            }
856
                        });
857
858
                        cb();
859
                    });
860
                },
861
                function() {
862
                    assert(_.uniq(changeIdxs).length > 1);
863
864
                    cb();
865
                }
866
            );
867
        });
868
869
        it("should be able to build a transaction", function(cb) {
0 ignored issues
show
Unused Code introduced by
The parameter cb is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
870
            wallet.getNewAddress(function(err, address, path) {
871
                assert.ifError(err);
872
                assert.ok(path.indexOf("M/9999'/0/") === 0);
873
                assert.ok(bitcoin.address.fromBase58Check(address));
874
875
                var pay = {};
876
                pay[address] = blocktrail.toSatoshi(0.001);
877
878
                wallet.buildTransaction(pay, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
879
                    assert.ifError(err);
880
                    assert.ok(tx);
881
                    assert.ok(tx.toHex());
882
                });
883
            });
884
        });
885
    });
886
887
    it("should be able to do a payment", function(cb) {
888
        wallet.getNewAddress(function(err, address, path) {
889
            assert.ifError(err);
890
            assert.ok(path.indexOf("M/9999'/", wallet.chain, "/") === 0);
891
            assert.ok(bitcoin.address.fromBase58Check(address));
892
893
            var pay = {};
894
            pay[address] = blocktrail.toSatoshi(0.001);
895
896
            var progress = [];
897
898
            wallet.pay(pay, function(err, txHash) {
899
                assert.ifError(err);
900
                assert.ok(txHash);
901
902
                // change address doesn't always happen ...
903
                if (progress.indexOf(blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS) === -1) {
904
                    progress.splice(2, 0, blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS);
905
                }
906
907
                assert.deepEqual(progress, [
908
                    blocktrail.Wallet.PAY_PROGRESS_START,
909
                    blocktrail.Wallet.PAY_PROGRESS_COIN_SELECTION,
910
                    blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS,
911
                    blocktrail.Wallet.PAY_PROGRESS_SIGN,
912
                    blocktrail.Wallet.PAY_PROGRESS_SEND,
913
                    blocktrail.Wallet.PAY_PROGRESS_DONE
914
                ]);
915
916
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
917
                setTimeout(function() {
918
                    client.transaction(txHash, function(err, tx) {
919
                        assert.ifError(err);
920
                        assert.ok(tx);
921
922
                        cb();
923
                    });
924
                }, WAIT_FOR_TX_PROCESSED);
925
            }).progress(function(_progress) {
926
                progress.push(_progress);
927
            });
928
        });
929
    });
930
});
931
932
describe('test wallet with segwit chain', function() {
933
    var wallet;
934
935
    it("should exist and be setup", function(cb) {
936
        client.initWallet({
937
            identifier: "unittest-transaction-sw",
938
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
939
        }, function(err, _wallet) {
940
            assert.ifError(err);
941
            assert.ok(_wallet);
942
            assert.equal(_wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
943
            assert.equal(_wallet.identifier, "unittest-transaction-sw");
944
            assert.equal(_wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
945
            assert.ok(_wallet.isSegwit());
946
            assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
947
            assert.equal(blocktrail.Wallet.CHAIN_BTC_SEGWIT, _wallet.changeChain);
948
949
            wallet = _wallet;
950
            cb();
951
        });
952
    });
953
954
    it("getNewAddress produces plain P2SH addresses", function(cb) {
955
        wallet.getNewAddress(function(err, address, path) {
956
            assert.ifError(err);
957
            assert.ok(path.indexOf("M/9999'/0/") === 0);
958
959
            assert.ok(bitcoin.address.fromBase58Check(address));
960
961
            cb();
962
        });
963
    });
964
965
    it("getNewAddress produces segwit P2SH addresses for change chain", function(cb) {
966
        wallet.getNewAddress(wallet.changeChain, function(err, address, path) {
967
            assert.ifError(err);
968
            assert.ok(path.indexOf("M/9999'/2/") === 0);
969
970
            assert.ok(bitcoin.address.fromBase58Check(address));
971
972
            cb();
973
        });
974
    });
975
976
    it("getWalletScriptByPath produces P2SH addresses, and returns witnessScript", function(cb) {
977
        var eAddress = "2N3j4Vx3D9LPumjtRbRe2RJpwVocvCCkHKh";
978
979
        assert.equal(wallet.getAddressByPath("M/9999'/2/0"), eAddress);
980
981
        var walletScript = wallet.getWalletScriptByPath("M/9999'/2/0");
982
        assert.equal(walletScript.address, eAddress);
983
        assert.ok(walletScript.witnessScript);
984
        assert.ok(walletScript.redeemScript);
985
        cb();
986
    });
987
});
988
989
describe('test wallet, do transaction, segwit spend', function() {
990
    var wallets = [];
991
    after(function(cb) {
992
        if (wallets.length > 0) {
993
            wallets.map(function(wallet) {
994
                wallet.deleteWallet(true);
995
            });
996
        }
997
        cb();
998
    });
999
1000
    var unitTestWallet;
1001
    var identifier = crypto.randomBytes(12).toString('hex');
1002
    var segwitWallet;
1003
    var receiveAddr;
1004
    var receiveBackAddr;
1005
    it("should setup the funding wallet", function(cb) {
1006
        client.initWallet({
1007
            identifier: "unittest-transaction",
1008
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1009
        }, function(err, _wallet) {
1010
            assert.ifError(err);
1011
            assert.ok(_wallet);
1012
1013
            _wallet.getNewAddress(function(err, address, path) {
1014
                assert.ifError(err);
1015
                assert.ok(address);
1016
                assert.ok(path);
1017
1018
                unitTestWallet = _wallet;
1019
                receiveBackAddr = address;
1020
                cb();
1021
            });
1022
        });
1023
    });
1024
1025
    it("should make the receiving segwit wallet", function(cb) {
1026
        createTransactionTestWallet(identifier, true, function(err, newWallet) {
1027
            wallets.push(newWallet);
1028
            assert.ifError(err);
1029
            newWallet.getNewAddress(newWallet.changeChain, function(err, address, path) {
1030
                assert.ifError(err);
1031
                assert.ok(bitcoin.address.fromBase58Check(address));
1032
                assert.ok(newWallet.isSegwit());
1033
                assert.ok(path.indexOf("M/9999'/2/") === 0);
1034
1035
                var checkScript = newWallet.getWalletScriptByPath(path);
1036
                assert.ok(checkScript.address = address);
1037
                assert.ok(checkScript.redeemScript instanceof Buffer);
0 ignored issues
show
Bug introduced by
The variable Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
1038
                assert.ok(checkScript.witnessScript instanceof Buffer);
1039
1040
                segwitWallet = newWallet;
1041
                receiveAddr = address;
1042
                cb();
1043
            });
1044
        });
1045
    });
1046
1047
    var paymentHash;
1048
    it("should receive funds from unitTestWallet", function(cb) {
1049
        var pay = {};
1050
        pay[receiveAddr] = 30000;
1051
        unitTestWallet.pay(pay, null, true, function(err, txid) {
1052
            assert.ifError(err);
1053
            assert.ok(txid);
1054
            paymentHash = txid;
0 ignored issues
show
Unused Code introduced by
The variable paymentHash seems to be never used. Consider removing it.
Loading history...
1055
            cb();
1056
        });
1057
    });
1058
1059
    it("should return to unitTestWallet", function(cb) {
1060
        var pay = {};
1061
        pay[receiveBackAddr] = 20000;
1062
        segwitWallet.pay(pay, null, true, function(err, txid) {
1063
            assert.ifError(err);
1064
            assert.ok(txid);
1065
1066
            setTimeout(function() {
1067
                client.transaction(txid, function(err, tx) {
1068
                    assert.ifError(err);
1069
                    assert.ok(tx);
1070
                    cb();
1071
                });
1072
            }, WAIT_FOR_TX_PROCESSED);
1073
        });
1074
    });
1075
});
1076
describe('test wallet, do transaction, without mnemonics', function() {
1077
    var wallet;
1078
1079
    var primarySeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_PASSWORD);
1080
1081
    it("should exists", function(cb) {
1082
        client.initWallet({
1083
                identifier: "unittest-transaction",
1084
                primarySeed: primarySeed,
1085
                primaryMnemonic: false // explicitly set false because we're reusing unittest-transaction which has a mnemonic stored
1086
            }, function(err, _wallet) {
1087
                assert.ifError(err);
1088
                assert.ok(_wallet);
1089
1090
                wallet = _wallet;
1091
1092
                assert.equal(wallet.identifier, "unittest-transaction");
1093
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1094
                cb();
1095
            }
1096
        );
1097
    });
1098
1099
    it("should have the expected addresses", function(cb) {
1100
        assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD");
1101
        assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2MynrezSyqCq1x5dMPtRDupTPA4sfVrNBKq");
1102
        assert.equal(wallet.getAddressByPath("M/9999'/0/44"), "2N5eqrZE7LcfRyCWqpeh1T1YpMdgrq8HWzh");
1103
1104
        cb();
1105
    });
1106
1107
    it("should have a balance", function(cb) {
1108
        this.timeout(0);
1109
1110
        wallet.getBalance(function(err, confirmed, unconfirmed) {
1111
            assert.ok(confirmed + unconfirmed > 0);
1112
            assert.ok(confirmed > 0);
1113
1114
            cb();
1115
        });
1116
    });
1117
1118
    it("should be able to do a payment", function(cb) {
1119
        wallet.getNewAddress(function(err, address, path) {
1120
            assert.ifError(err);
1121
            assert.ok(path.indexOf("M/9999'/0/") === 0);
1122
            assert.ok(bitcoin.address.fromBase58Check(address));
1123
1124
            var pay = {};
1125
            pay[address] = blocktrail.toSatoshi(0.001);
1126
1127
            wallet.pay(pay, function(err, txHash) {
1128
                assert.ifError(err);
1129
                assert.ok(txHash);
1130
1131
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1132
                setTimeout(function() {
1133
                    client.transaction(txHash, function(err, tx) {
1134
                        assert.ifError(err);
1135
                        assert.ok(tx);
1136
1137
                        cb();
1138
                    });
1139
                }, WAIT_FOR_TX_PROCESSED);
1140
            });
1141
        });
1142
    });
1143
});
1144
1145
describe('test wallet, do opreturn transaction', function() {
1146
    var wallet;
1147
1148
    it("should exists", function(cb) {
1149
        client.initWallet({
1150
            identifier: "unittest-transaction",
1151
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1152
        }, function(err, _wallet) {
1153
            assert.ifError(err);
1154
            assert.ok(_wallet);
1155
1156
            wallet = _wallet;
1157
1158
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1159
            assert.equal(wallet.identifier, "unittest-transaction");
1160
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1161
            cb();
1162
        });
1163
    });
1164
1165
    it("should be able to do a payment with opreturn output", function(cb) {
1166
        wallet.getNewAddress(function(err, address, path) {
0 ignored issues
show
Unused Code introduced by
The parameter path is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1167
            assert.ifError(err);
1168
1169
            var pay = {};
1170
            pay[address] = blocktrail.toSatoshi(0.001);
1171
            pay[blocktrail.Wallet.OP_RETURN] = "BLOCKTRAILTESTDATA";
1172
1173
            wallet.pay(pay, function(err, txHash) {
1174
                assert.ifError(err);
1175
                assert.ok(txHash);
1176
1177
1178
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1179
                setTimeout(function() {
1180
                    client.transaction(txHash, function(err, tx) {
1181
                        assert.ifError(err);
1182
                        assert.ok(tx);
1183
1184
                        var hasOpreturn;
1185
                        tx.outputs.forEach(function(output) {
1186
                            if (output.type === 'op_return') {
1187
                                hasOpreturn = true;
1188
1189
                                assert.equal(output.script_hex, "6a12424c4f434b545241494c5445535444415441");
1190
                            }
1191
                        });
1192
                        assert.ok(hasOpreturn);
1193
1194
                        cb();
1195
                    });
1196
                }, WAIT_FOR_TX_PROCESSED);
1197
            });
1198
        });
1199
    });
1200
});
1201
1202
describe('test wallet, do forcefee transaction', function() {
1203
    var wallet;
1204
1205
    it("should exists", function(cb) {
1206
        client.initWallet({
1207
            identifier: "unittest-transaction",
1208
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1209
        }, function(err, _wallet) {
1210
            assert.ifError(err);
1211
            assert.ok(_wallet);
1212
1213
            wallet = _wallet;
1214
1215
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1216
            assert.equal(wallet.identifier, "unittest-transaction");
1217
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1218
            cb();
1219
        });
1220
    });
1221
1222
    it("should be able to do a payment with forced fee", function(cb) {
1223
        wallet.getNewAddress(function(err, address, path) {
0 ignored issues
show
Unused Code introduced by
The parameter path is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1224
            assert.ifError(err);
1225
1226
            var pay = {};
1227
            pay[address] = blocktrail.toSatoshi(0.01);
1228
            var forceFee = blocktrail.toSatoshi(0.00054321);
1229
1230
            wallet.pay(pay, null, false, true, blocktrail.Wallet.FEE_STRATEGY_FORCE_FEE, null, {
1231
                forcefee: forceFee,
1232
                checkFee: false
1233
            }, function(err, txHash) {
1234
                assert.ifError(err);
1235
                assert.ok(txHash);
1236
1237
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1238
                setTimeout(function() {
1239
                    client.transaction(txHash, function(err, tx) {
1240
                        assert.ifError(err);
1241
                        // this could very occasionally fail if change < DUST because then it's added to fee, so adjusted check for that
1242
                        assert.ok(tx['total_fee'] >= forceFee && tx['total_fee'] <= forceFee + blocktrail.DUST,
1243
                            "fee [" + tx['total_fee'] + "] should be equal to forced fee [" +  forceFee + "] for tx [" + txHash + "]");
1244
1245
                        cb();
1246
                    });
1247
                }, WAIT_FOR_TX_PROCESSED);
1248
            });
1249
        });
1250
    });
1251
});
1252
1253
describe('test wallet discovery and upgrade key index', function() {
1254
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1255
    var wallet;
1256
1257
    after(function(cb) {
1258
        if (wallet) {
1259
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1260
                cb();
1261
            });
1262
        } else {
1263
            cb();
1264
        }
1265
    });
1266
1267
    it("should be created", function(cb) {
1268
        createDiscoveryTestWallet(myIdentifier, "password", function(err, _wallet) {
1269
            assert.ifError(err);
1270
            assert.ok(_wallet);
1271
            _wallet.chain = blocktrail.Wallet.CHAIN_BTC_DEFAULT;
1272
            wallet = _wallet;
1273
1274
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole kingdom");
1275
            assert.equal(wallet.identifier, myIdentifier);
1276
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1277
1278
            cb();
1279
        });
1280
    });
1281
1282
    it("should have the expected addresses", function(cb) {
1283
        async.series([
1284
            function(cb) {
1285
                wallet.getNewAddress(function(err, address, path) {
1286
                    assert.ifError(err);
1287
                    assert.equal(path, "M/9999'/0/0");
1288
                    assert.equal(address, "2Mtfn5S9tVWnnHsBQixCLTsCAPFHvfhu6bM");
1289
1290
                    cb();
1291
                });
1292
            },
1293
            function(cb) {
1294
                wallet.getNewAddress(function(err, address, path) {
1295
                    assert.ifError(err);
1296
                    assert.equal(path, "M/9999'/0/1");
1297
                    assert.equal(address, "2NG49GDkm5qCYvDFi4cxAnkSho8qLbEz6C4");
1298
1299
                    cb();
1300
                });
1301
            },
1302
            function(cb) {
1303
                assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2NG49GDkm5qCYvDFi4cxAnkSho8qLbEz6C4");
1304
                assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2N1kM5xeDaCN9Weog3mbyxjpryNZcirnkB7");
1305
1306
                cb();
1307
            }
1308
        ], cb);
1309
    });
1310
1311
    it("should have a balance after discovery", function(cb) {
1312
        this.timeout(0);
1313
1314
        wallet.doDiscovery(50, function(err, confirmed, unconfirmed) {
1315
            assert.ok(confirmed + unconfirmed > 0);
1316
1317
            cb();
1318
        });
1319
    });
1320
1321
    it("should be upgraded and have expected addresses", function(cb) {
1322
        // set upgrade
1323
        wallet.upgradeToKeyIndex = 10000;
1324
        // lock
1325
        wallet.lock();
1326
        // unlock should upgrade
1327
        wallet.unlock({
1328
            passphrase: "password"
1329
        }).then(function() {
1330
            assert.equal(wallet.getBlocktrailPublicKey("M/10000'").toBase58(), "tpubD9m9hziKhYQExWgzMUNXdYMNUtourv96sjTUS9jJKdo3EDJAnCBJooMPm6vGSmkNTNAmVt988dzNfNY12YYzk9E6PkA7JbxYeZBFy4XAaCp");
1331
1332
            assert.equal(wallet.getAddressByPath("M/10000'/0/0"), "2N9ZLKXgs12JQKXvLkngn7u9tsYaQ5kXJmk");
1333
1334
            wallet.getNewAddress(function(err, address, path) {
1335
                assert.ifError(err);
1336
                assert.equal(path, "M/10000'/0/0");
1337
                assert.equal(address, "2N9ZLKXgs12JQKXvLkngn7u9tsYaQ5kXJmk");
1338
1339
                cb();
1340
            });
1341
        });
1342
    });
1343
});
1344
1345
describe('test wallet with bad password', function() {
1346
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1347
    var wallet;
1348
1349
    after(function(cb) {
1350
        if (wallet) {
1351
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1352
                cb();
1353
            });
1354
        } else {
1355
            cb();
1356
        }
1357
    });
1358
1359
    it("should be created", function(cb) {
1360
        createDiscoveryTestWallet(myIdentifier, "badpassword", function(err, _wallet) {
1361
            assert.ifError(err);
1362
            assert.ok(_wallet);
1363
1364
            _wallet.chain = blocktrail.Wallet.CHAIN_BTC_DEFAULT;
1365
            wallet = _wallet;
1366
1367
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole kingdom");
1368
            assert.equal(wallet.identifier, myIdentifier);
1369
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1370
1371
            cb();
1372
        });
1373
    });
1374
1375
    it("should have the expected addresses (different from with the correct password)", function(cb) {
1376
        async.series([
1377
            function(cb) {
1378
                wallet.getNewAddress(function(err, address, path) {
1379
                    assert.ifError(err);
1380
                    assert.equal(path, "M/9999'/0/0");
1381
                    assert.equal(address, "2N9SGrV4NKRjdACYvHLPpy2oiPrxTPd44rg");
1382
1383
                    cb();
1384
                });
1385
            },
1386
            function(cb) {
1387
                wallet.getNewAddress(function(err, address, path) {
1388
                    assert.ifError(err);
1389
                    assert.equal(path, "M/9999'/0/1");
1390
                    assert.equal(address, "2NDq3DRy9E3YgHDA3haPJj3FtUS6V93avkf");
1391
1392
                    cb();
1393
                });
1394
            }
1395
        ], cb);
1396
    });
1397
1398
    it("shouldn't have a balance after discovery", function(cb) {
1399
        this.timeout(0);
1400
1401
        wallet.doDiscovery(50, function(err, confirmed, unconfirmed) {
1402
            assert.ok(confirmed + unconfirmed === 0);
1403
1404
            cb();
1405
        });
1406
    });
1407
});
1408
1409
describe('test wallet webhook', function() {
1410
    // this.timeout(0); // disable, can take long
1411
1412
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1413
    var wallet;
1414
1415
    after(function(cb) {
1416
        if (wallet) {
1417
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1418
                cb();
1419
            });
1420
        } else {
1421
            cb();
1422
        }
1423
    });
1424
1425
    it("shouldn't already exist", function(cb) {
1426
        client.initWallet({
1427
            identifier: myIdentifier,
1428
            passphrase: "password"
1429
        }, function(err, wallet) {
1430
            assert.ok(err);
1431
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
1432
1433
            cb();
1434
        });
1435
    });
1436
1437
    it("should be created", function(cb) {
1438
        client.createNewWallet({
1439
            identifier: myIdentifier,
1440
            passphrase: "password",
1441
            keyIndex: 9999
1442
        }, function(err, _wallet) {
1443
            assert.ifError(err);
1444
            assert.ok(_wallet);
1445
1446
            wallet = _wallet;
1447
1448
            assert.equal(wallet.identifier, myIdentifier);
1449
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1450
            cb();
1451
        });
1452
    });
1453
1454
    it("should have a 0 balance", function(cb) {
1455
        wallet.getBalance(function(err, confirmed, unconfirmed) {
1456
            assert.ifError(err);
1457
            assert.equal(confirmed, 0);
1458
            assert.equal(unconfirmed, 0);
1459
1460
            cb();
1461
        });
1462
    });
1463
1464
    it("should be able to create a webhook", function(cb) {
1465
        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", function(err, webhook) {
1466
            assert.ifError(err);
1467
            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1468
            assert.equal(webhook['identifier'], "WALLET-" + myIdentifier);
1469
1470
            wallet.deleteWebhook(function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1471
                assert.ifError(err);
1472
1473
                cb();
1474
            });
1475
        });
1476
    });
1477
1478
    it("should be able to create a webhook with custom identifier", function(cb) {
1479
        var myWebhookIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1480
1481
        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", myWebhookIdentifier, function(err, webhook) {
1482
            assert.ifError(err);
1483
            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1484
            assert.equal(webhook['identifier'], myWebhookIdentifier);
1485
1486
            client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1487
                assert.ifError(err);
1488
1489
                wallet.getNewAddress(function(err, address1) {
1490
                    assert.ifError(err);
1491
1492
                    wallet.deleteWebhook(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1493
                        assert.ifError(err);
1494
1495
                        var myWebhookIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1496
1497
                        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", myWebhookIdentifier, function(err, webhook) {
1498
                            assert.ifError(err);
1499
                            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1500
                            assert.equal(webhook['identifier'], myWebhookIdentifier);
1501
1502
                            client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
1503
                                assert.ifError(err);
1504
                                assert.ok(_.includes(_.map(result['data'], 'address'), address1));
1505
1506
                                wallet.getNewAddress(function(err, address2) {
1507
                                    assert.ifError(err);
1508
1509
                                    client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
1510
                                        assert.ifError(err);
1511
                                        assert.ok(_.includes(_.map(result['data'], 'address'), address2));
1512
1513
                                        wallet.deleteWallet(function(err, result) {
1514
                                            assert.ifError(err);
1515
                                            assert.ok(result);
1516
1517
                                            client.deleteWebhook(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1518
                                                assert.ok(err);
1519
1520
                                                cb();
1521
                                            });
1522
                                        });
1523
                                    });
1524
                                });
1525
                            });
1526
                        });
1527
                    });
1528
1529
                });
1530
            });
1531
        });
1532
    });
1533
});
1534
1535
describe("Wallet.getAddressAndType", function() {
1536
    var fixtures = [
1537
        {
1538
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1539
            network: bitcoin.networks.testnet,
1540
            type: "bech32",
1541
            valid: true
1542
        },
1543
        {
1544
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1545
            network: bitcoin.networks.testnet,
1546
            type: "bech32",
1547
            valid: true
1548
        },
1549
        {
1550
            address: "muinVykhtZyonxQxk8zBptX6Lmri91bdNG",
1551
            network: bitcoin.networks.testnet,
1552
            type: "base58",
1553
            valid: true
1554
        },
1555
        {
1556
            address: "2N7T4CD6CEuNHJoGKpoJH3YexqektXjyy6L",
1557
            network: bitcoin.networks.testnet,
1558
            type: "base58",
1559
            valid: true
1560
        },
1561
        {
1562
            address: "16uf9UUBbUHdVAnETGZQnvXZcf9NPU1QR6",
1563
            network: bitcoin.networks.bitcoin,
1564
            type: "base58",
1565
            valid: true
1566
        },
1567
        {
1568
            address: "3CgSFohdEqd7pSxbDAJeJo6X5Qm2tBbby9",
1569
            network: bitcoin.networks.bitcoin,
1570
            type: "base58",
1571
            valid: true
1572
        },
1573
        {
1574
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1575
            network: bitcoin.networks.bitcoin,
1576
            type: "bech32",
1577
            valid: true
1578
        },
1579
        {
1580
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1581
            network: bitcoin.networks.bitcoin,
1582
            type: "bech32",
1583
            valid: true
1584
        },
1585
        {
1586
            address: "16uf9UUBbUHdVAnETGZQnvXZcf9NPU1QR6",
1587
            network: bitcoin.networks.testnet,
1588
            type: "base58",
1589
            error: "Address invalid on this network",
1590
            valid: false
1591
        },
1592
        {
1593
            address: "3CgSFohdEqd7pSxbDAJeJo6X5Qm2tBbby9",
1594
            network: bitcoin.networks.testnet,
1595
            type: "base58",
1596
            error: "Address invalid on this network",
1597
            valid: false
1598
        },
1599
        {
1600
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1601
            network: bitcoin.networks.testnet,
1602
            type: "bech32",
1603
            error: "Address invalid on this network",
1604
            valid: false
1605
        },
1606
        {
1607
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1608
            network: bitcoin.networks.testnet,
1609
            type: "bech32",
1610
            error: "Address invalid on this network",
1611
            valid: false
1612
        },
1613
        {
1614
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1615
            network: bitcoin.networks.bitcoincash,
1616
            error: "Non-base58 character",
1617
            type: "bech32",
1618
            valid: false
1619
        },
1620
        {
1621
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1622
            network: bitcoin.networks.bitcoincash,
1623
            error: "Non-base58 character",
1624
            type: "bech32",
1625
            valid: false
1626
        },
1627
        {
1628
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1629
            network: bitcoin.networks.bitcoincashtestnet,
1630
            error: "Non-base58 character",
1631
            type: "bech32",
1632
            valid: false
1633
        },
1634
        {
1635
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1636
            network: bitcoin.networks.bitcoincashtestnet,
1637
            error: "Non-base58 character",
1638
            type: "bech32",
1639
            valid: false
1640
        },
1641
        {
1642
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1643
            network: bitcoin.networks.bitcoin,
1644
            error: "Address invalid on this network",
1645
            type: "bech32",
1646
            valid: false
1647
        },
1648
        {
1649
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1650
            network: bitcoin.networks.bitcoin,
1651
            error: "Address invalid on this network",
1652
            type: "bech32",
1653
            valid: false
1654
        },
1655
        {
1656
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1657
            network: bitcoin.networks.testnet,
1658
            error: "Address invalid on this network",
1659
            type: "bech32",
1660
            valid: false
1661
        },
1662
        {
1663
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1664
            network: bitcoin.networks.testnet,
1665
            error: "Address invalid on this network",
1666
            type: "bech32",
1667
            valid: false
1668
        }
1669
    ];
1670
1671
    fixtures.map(function(fixture) {
1672
        var description =
1673
            (fixture.valid ? "parses" : "fails to parse") +
1674
            " a " + fixture.type + " address: " + fixture.address;
1675
1676
        it(description, function(cb) {
1677
            var addrAndType;
1678
            var err;
1679
            try {
1680
                addrAndType = Wallet.getAddressAndType(fixture.address, fixture.network);
1681
            } catch (e) {
1682
                err = e;
1683
            }
1684
1685
            if (fixture.valid) {
1686
                assert.ifError(err);
0 ignored issues
show
Bug introduced by
The variable err seems to not be initialized for all possible execution paths. Are you sure ifError handles undefined variables?
Loading history...
1687
                assert.ok(Object.keys(addrAndType).indexOf("address") !== -1);
1688
                assert.ok(Object.keys(addrAndType).indexOf("decoded") !== -1);
1689
                assert.ok(Object.keys(addrAndType).indexOf("type") !== -1);
1690
                assert.equal(addrAndType.type, fixture.type);
1691
                assert.equal(addrAndType.address, fixture.address);
1692
            } else {
1693
                assert.ok(typeof err === "object");
1694
                assert.ok(typeof addrAndType === "undefined");
1695
                if (Object.keys(fixture).indexOf("error") !== -1) {
1696
                    assert.equal(err.message, fixture.error);
1697
                }
1698
            }
1699
            cb();
1700
        });
1701
    });
1702
});
1703
1704
describe("Wallet.convertPayToOutputs", function() {
1705
    var network = bitcoin.networks.testnet;
1706
    var fixtures = [
1707
        {
1708
            description: "p2wpkh",
1709
            network: bitcoin.networks.testnet,
1710
            value: 12345,
1711
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1712
            script: "00149bce9399f9eeddad66635d4be171ec8f14decc59"
1713
        },
1714
        {
1715
            description: "p2wsh",
1716
            network: bitcoin.networks.testnet,
1717
            value: 12345,
1718
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1719
            script: "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262"
1720
        },
1721
        {
1722
            description: "p2pkh",
1723
            network: bitcoin.networks.testnet,
1724
            value: 12345,
1725
            address: "muinVykhtZyonxQxk8zBptX6Lmri91bdNG",
1726
            script: "76a9149bce9399f9eeddad66635d4be171ec8f14decc5988ac"
1727
        },
1728
        {
1729
            description: "p2sh",
1730
            network: bitcoin.networks.testnet,
1731
            value: 12345,
1732
            address: "2N7T4CD6CEuNHJoGKpoJH3YexqektXjyy6L",
1733
            script: "a9149bce9399f9eeddad66635d4be171ec8f14decc5987"
1734
        }
1735
    ];
1736
1737
    fixtures.map(function(fixture, i) {
1738
1739
        it(fixture.description + " converted to script, " + i, function(cb) {
1740
            var test = function(outputs) {
1741
                assert.ok(Array.isArray(outputs));
1742
                assert.equal(outputs[0].value, fixture.value);
1743
                assert.equal(outputs[0].scriptPubKey, fixture.script);
1744
                assert.equal(outputs[0].address, null);
1745
            };
1746
1747
            // should accept some input of ours
1748
            var pay = [{
1749
                scriptPubKey: fixture.script,
1750
                value: fixture.value
1751
            }];
1752
1753
            var outputs = Wallet.convertPayToOutputs(pay, network);
1754
            test(outputs);
1755
1756
            pay = {};
1757
            pay[fixture.address] = fixture.value;
1758
1759
            // should deal with simple mapping form
1760
            outputs = Wallet.convertPayToOutputs(pay, network);
1761
            test(outputs);
1762
1763
            // repeating the procedure should pass the same test
1764
            outputs = Wallet.convertPayToOutputs(outputs, network);
1765
            test(outputs);
1766
1767
            cb();
1768
        });
1769
    });
1770
});
1771
1772
describe('test wallet coin selection forms', function() {
1773
    var wallet;
1774
1775
    it("BTC testnet wallet should exist", function(cb) {
1776
        client.initWallet({
1777
            identifier: "unittest-transaction",
1778
            passphrase: "password"
1779
        }, function(err, _wallet) {
1780
            assert.ifError(err);
1781
            assert.ok(_wallet);
1782
1783
            wallet = _wallet;
1784
1785
            client.allWallets({page: 1}, function(err, wallets) {
1786
                assert.ifError(err);
1787
1788
                assert.ok(wallets['data'].length > 0);
1789
1790
                assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1791
                assert.equal(wallet.identifier, "unittest-transaction");
1792
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1793
1794
                cb();
1795
            });
1796
        });
1797
    });
1798
1799
    it("shouldnt coin select for wrong network", function(cb) {
1800
        var pay = {};
1801
        pay["bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42"] = 10000;
1802
        wallet.coinSelection(pay, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1803
            assert.ok(err);
1804
            cb();
1805
        });
1806
    });
1807
1808
    var fixtures = [
1809
        {"tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs": 10000},
1810
        {"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7": 10000},
1811
        [
1812
            {
1813
                "address": "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1814
                "value": 10000
1815
            },
1816
            {
1817
                "address": "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1818
                "value": 10000
1819
            }
1820
        ],
1821
        [
1822
            {
1823
                "scriptPubKey": "00149bce9399f9eeddad66635d4be171ec8f14decc59",
1824
                "value": 10000
1825
            },
1826
            {
1827
                "address": "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1828
                "value": 10000
1829
            }
1830
        ]
1831
    ];
1832
1833
    fixtures.map(function(fixture) {
1834
        var type = "object";
1835
        if (Array.isArray(fixture)) {
1836
            type = "outputs array";
1837
        }
1838
        it("should coin select for " + type, function(cb) {
1839
            wallet.coinSelection(fixture, false, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1840
                assert.ifError(err);
1841
                cb();
1842
            });
1843
        });
1844
    });
1845
});
1846
1847
describe('test wallet list transactions and addresses', function() {
1848
    var wallet;
1849
1850
    it("should exists", function(cb) {
1851
        client.initWallet({
1852
            identifier: "unittest-transaction",
1853
            passphrase: "password"
1854
        }, function(err, _wallet) {
1855
            assert.ifError(err);
1856
            assert.ok(_wallet);
1857
1858
            wallet = _wallet;
1859
1860
            client.allWallets({page: 1}, function(err, wallets) {
1861
                assert.ifError(err);
1862
1863
                assert.ok(wallets['data'].length > 0);
1864
1865
                assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1866
                assert.equal(wallet.identifier, "unittest-transaction");
1867
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1868
1869
                cb();
1870
            });
1871
        });
1872
    });
1873
1874
    it("should list expected transactions", function(cb) {
1875
        wallet.transactions({page: 1, limit: 23}, function(err, transactions) {
1876
            assert.ifError(err);
1877
            assert.ok(transactions['data']);
1878
            assert.ok(transactions['total']);
1879
            assert.ok(transactions['data'].length === 23);
1880
            assert.ok(transactions['data'][0]['hash'], "2cb21783635a5f22e9934b8c3262146b42d251dfb14ee961d120936a6c40fe89");
1881
1882
            cb();
1883
        });
1884
    });
1885
1886
    it("should list expected addresses", function(cb) {
1887
        wallet.addresses({page: 1, limit: 23}, function(err, addresses) {
1888
            assert.ifError(err);
1889
            assert.ok(addresses['data']);
1890
            assert.ok(addresses['total']);
1891
            assert.ok(addresses['data'].length === 23);
1892
            assert.ok(addresses['data'][0]['address'], "2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS");
1893
1894
            cb();
1895
        });
1896
    });
1897
1898
    it("should list UTXOs", function(cb) {
1899
        wallet.utxos({page: 0, limit: 23}, function(err, addresses) {
1900
            assert.ifError(err);
1901
            assert.ok(addresses['data']);
1902
            assert.ok(addresses['total']);
1903
            assert.ok(addresses['data'].length === 23);
1904
1905
            cb();
1906
        });
1907
    });
1908
});
1909
1910
describe("size estimation", function() {
1911
1912
    it("should estimate proper size for 1 input 1 output TX", function() {
1913
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1914
        txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', 0);
1915
        txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1916
1917
        assert.equal(347, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1918
    });
1919
1920
    it("should estimate proper size for 99 inputs 1 output TX", function() {
1921
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1922
        for (var i = 0; i < 99; i++) {
1923
            txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', i);
1924
        }
1925
        txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1926
1927
        assert.equal(29453, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1928
    });
1929
1930
    it("should estimate proper size for 1 input 99 outputs TX", function() {
1931
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1932
        txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', 0);
1933
        for (var i = 0; i < 99; i++) {
1934
            txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1935
        }
1936
1937
        assert.equal(3679, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1938
    });
1939
});
1940
1941
describe("APIClient", function() {
1942
    it("resolvePrimaryPrivateKeyFromOptions", function(cb) {
1943
        client.resolvePrimaryPrivateKeyFromOptions({
1944
            passphrase: "password",
1945
            primaryMnemonic: "give pause forget seed dance crawl situate hole keen"
1946
        }, function(err, options) {
1947
            assert.ifError(err);
1948
            assert.ok(options.primaryPrivateKey);
1949
            assert.ok(options.primaryPrivateKey instanceof bitcoin.HDNode);
1950
            assert.equal("tprv8ZgxMBicQKsPeR93md5eVTbLDgQ8kfV4CDNtrVXv5p29KXtx7VHKFQThGkFgC61sYeeeaVH1yFv4thcvxS9cYdFrYwTNmkGhkQEJycSzAhE", options.primaryPrivateKey.toBase58());
1951
1952
            cb();
1953
1954
        });
1955
    });
1956
});
1957